這個禮拜從公司老闆那得到一句話,並時時提醒自己:觀念不能用背的,不然永遠都搞不懂,這樣會很辛苦。
今天的學習算是之前對於 this 觀念的複習,並更加深印象。
(正文開始)
我知道 「 this 會指向一個物件; this 不在乎函式怎麼被定義、或者在哪裡定義,只在乎函式 "被誰呼叫",這個誰很重要,很重要,很重要」;
函式有兩項特性,會影響著函式可以 access 到哪些變數:
scope 在「定義函式」之後就固定不變了,其可以調用的變數已經決定好了; 所以函式怎麼被定義會影響 scope。
但是函式的 execution context 一直在改變,這完全取決於函式「怎麼被呼叫」。
( execution context 在函式被呼叫的時後才會生成,由 function parameters, local variables, and this
value)
this 的 value 在「執行函式」的時候才會被決定,誰呼叫了這個函式,this 會指向那個呼叫的物件,所以函式的 this value 在每次執行函式的時候都不一樣。
function classroom(teacher) {
return function study() {
// study 函式是 context-aware,因為它參考到了 `this`
console.log(`${ teacher } says to study ${ this.topic }`);
}
}
var assignment = classroom('Kyle');
// 由 classroom 函式回傳的 study 函式被 assign 到 assignment 變數
assignment(); // Kyle says to study undefined
// 在不是嚴謹模式之下, context-aware 函式會預設全域物件作為 context
// 因為全域物件下沒有定義 topic ,所以 this.topic 會是 undefined
var homework = {
topic: 'JS',
assignment: assignment
};
homework.assignment(); // Kyle says to study JS
// 還記得一開始說的,影響 this 的 value 關鍵在於「被誰呼叫」
// homework 物件有個 assignment proterty,
// 其 value 就是 study 函式的 instance
// homework.assignment() 就是在呼叫 study 函式
// this 就會指向 homework 物件
var otherHomework = {
topic: 'Math'
};
assignment.call(otherHomework); // Kyle says to study Math
// 另外一個呼叫函式的方法,是 call
// call 會指定參數內的物件作為 this 的 value
// assignment(), homework.assignment(), 和 assignment.call(otherHomework)
// 這三種呼叫的方法都不一樣
// this 也都不同
// 再次驗證,this 取決於函式怎麼被呼叫、被誰呼叫
[ 參考 ]
-https://stackoverflow.com/questions/7721200/using-javascript-closures-in-settimeout/7722057#7722057
-https://stackoverflow.com/questions/9384758/what-is-the-execution-context-in-javascript-exactly
-https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/get-started/ch3.md#this-keyword